package main

import (
	"bufio"
	"database/sql"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"os"
	"strings"
	"sync"
)

var wg sync.WaitGroup

func main() {
	// 读
	handleChan := make(chan string, 100)
	// 写入文件
	fileChan := make(chan string, 20)
	// 写入数据库
	dbChan := make(chan string, 20)

	// 读取日志
	go readLog(handleChan)
	wg.Add(1)
	// 处理读取的数据
	go handle(handleChan, fileChan, dbChan)
	wg.Add(1)
	// 写入文件
	go writeFile(fileChan)
	wg.Add(1)
	// 写入数据库
	go writeDb(dbChan)
	wg.Add(1)
	wg.Wait()
}

// 读取文件内容
func readLog(handleChan chan string) {
	defer close(handleChan)
	defer wg.Done()
	path := []string{"D:\\code\\gin-learn\\hardy-log.sql", "D:\\code\\gin-learn\\hardy-log2.sql"}
	for src := range path {
		file, err := os.Open(path[src])
		if err != nil {
			fmt.Printf("read file Error:%s\n", err)
			return
		}
		buf := bufio.NewReader(file)
		for {
			l, e := buf.ReadBytes('\n')
			if e != nil && len(l) == 0 {
				break
			}
			handleChan <- string(l)
		}
		file.Close()
	}

}

// 写文件
func writeFile(fileChan chan string) {
	defer wg.Done()
	name := "file.sql"

	f, err := os.Create(name)
	if err != nil {
		fmt.Printf("wirte file Error:%s\n", err)
		return
	}
	defer f.Close()
	for s := range fileChan {
		sql := strings.Replace(s, "\\n", ";\n", -1)
		_, err = f.WriteString(sql)
		if err != nil {
			fmt.Printf("wirte file Error:%s\n", err)
			return
		}
	}
}

// 写入数据库
func writeDb(dbChan chan string) {
	defer wg.Done()
	db, err := sql.Open("mysql", "root:root@tcp(127.0.0.1:3306)/n?charset=utf8mb4")
	if err != nil {
		fmt.Println(err)
		os.Exit(0)
	}
	defer db.Close()
	for sql := range dbChan {
		_, err = db.Exec(sql)
		if err != nil {
			fmt.Println(err)
			fmt.Println(sql)
		}
	}
}

// 处理数据的合法性
func handle(handleChan, fileChan, dbChan chan string) {
	defer wg.Done()
	status, k := true, true
	defer close(fileChan)
	defer close(dbChan)
	for str := range handleChan {
		if strings.HasPrefix(str, "#200813  0:00:02 server id 1  end_log_pos 832887841") {
			status = false
			continue
		}
		if status {
			continue
		}
		if strings.HasPrefix(str, "#210129 16:41:09 server id 1  end_log_pos 753739614") {
			k = false
			continue
		}
		if !k {
			continue
		}

		if strings.HasPrefix(str, "#") {
			continue
		}
		if strings.HasPrefix(str, "/*") {
			continue
		}
		if strings.HasPrefix(str, "UPDATE `gy_posts`") || strings.HasPrefix(str, "DELETE FROM `gy_posts`") || strings.HasPrefix(str, "INSERT INTO `gy_posts`") {
			fileChan <- str
			dbChan <- str
		}
	}

}

//import (
//	"bufio"
//	"database/sql"
//	"fmt"
//	_ "github.com/go-sql-driver/mysql"
//	"os"
//	"strings"
//)
//var status = true
//var k = true
//var db *sql.DB
//var f *os.File
//
//func main() {
//	var err error
//	db,err = sql.Open("mysql", "root:root@tcp(127.0.0.1:3306)/b?charset=utf8mb4")
//	if err != nil{
//		fmt.Println(err)
//		os.Exit(0)
//	}
//	defer db.Close()
//	readFile("D:\\code\\gin-learn\\hardy-log.sql", "test11.sql")
//	readFile("D:\\code\\gin-learn\\hardy-log2.sql", "test22.sql")
//}
//
//func readFile(p string, name string){
//	var err error
//	f, err = os.Create(name)
//	if err != nil {
//		fmt.Println(err)
//		return
//	}
//	defer f.Close()
//
//	fi, err := os.Open(p)
//	if err != nil {
//		fmt.Printf("Error: %s\n", err)
//		return
//	}
//	defer fi.Close()
//
//	br := bufio.NewReader(fi)
//	for {
//		l,e := br.ReadBytes('\n')
//		if e != nil && len(l) == 0  {
//			break
//		}
//		handle(string(l))
//	}
//}
//
//func handle(str string)  {
//	if strings.HasPrefix(str, "#200813  0:00:02 server id 1  end_log_pos 832887841"){
//		status = false
//		return
//	}
//	if status {
//		return
//	}
//
//	if strings.HasPrefix(str, "#210129 16:41:09 server id 1  end_log_pos 753739614"){
//		k = false
//		return
//	}
//	if !k {
//		return
//	}
//
//	if strings.HasPrefix(str, "#"){
//		return
//	}
//	if strings.HasPrefix(str, "/*"){
//		return
//	}
//	if strings.HasPrefix(str, "UPDATE `gy_posts`") || strings.HasPrefix(str, "DELETE FROM `gy_posts`") || strings.HasPrefix(str, "INSERT INTO `gy_posts`"){
//		_, err := db.Exec(str)
//		if err != nil{
//			fmt.Println(err)
//			fmt.Println(str)
//		}
//		write(str)
//	}
//}
//func write(s string){
//	_, err := f.WriteString(s+"\n")
//	if err != nil {
//		fmt.Println(err)
//		return
//	}
//}
